﻿using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using vm.Aspects.Threading;

namespace vm.Aspects.Threading.Test
{
    [TestClass]
    public class LockSlimExtensionsTest
    {
        [TestMethod]
        public void TestReaderSync()
        {
            ReaderWriterLockSlim lck = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            using(var sync = lck.ReaderSync())
            {
                Assert.IsInstanceOfType(sync, typeof(ReaderSlimSync));

                Assert.IsTrue(lck.IsReadLockHeld);
                Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
                Assert.IsFalse(lck.IsWriteLockHeld);
            }

            Assert.IsFalse(lck.IsReadLockHeld);
            Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
            Assert.IsFalse(lck.IsWriteLockHeld);
        }

        [TestMethod]
        public void TestWriterSync()
        {
            ReaderWriterLockSlim lck = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            using(var sync = lck.WriterSync())
            {
                Assert.IsInstanceOfType(sync, typeof(WriterSlimSync));

                Assert.IsFalse(lck.IsReadLockHeld);
                Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
                Assert.IsTrue(lck.IsWriteLockHeld);
            }

            Assert.IsFalse(lck.IsReadLockHeld);
            Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
            Assert.IsFalse(lck.IsWriteLockHeld);
        }

        [TestMethod]
        public void TestUpgradableReaderSync()
        {
            ReaderWriterLockSlim lck = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            using(var sync = lck.UpgradableReaderSync())
            {
                Assert.IsInstanceOfType(sync, typeof(UpgradeableReaderSlimSync));

                Assert.IsFalse(lck.IsReadLockHeld);
                Assert.IsTrue(lck.IsUpgradeableReadLockHeld);
                Assert.IsFalse(lck.IsWriteLockHeld);

                using(lck.WriterSync())
                {
                    Assert.IsFalse(lck.IsReadLockHeld);
                    Assert.IsTrue(lck.IsUpgradeableReadLockHeld);
                    Assert.IsTrue(lck.IsWriteLockHeld);
                }
            }

            Assert.IsFalse(lck.IsReadLockHeld);
            Assert.IsFalse(lck.IsUpgradeableReadLockHeld);
            Assert.IsFalse(lck.IsWriteLockHeld);
        }
    }
}
